package com.xxh.chatdemo.handler;

import com.corundumstudio.socketio.AckRequest;
import com.corundumstudio.socketio.SocketIOClient;
import com.corundumstudio.socketio.SocketIOServer;
import com.corundumstudio.socketio.annotation.OnConnect;
import com.corundumstudio.socketio.annotation.OnDisconnect;
import com.corundumstudio.socketio.annotation.OnEvent;
import com.xxh.chatdemo.config.Event;
import com.xxh.chatdemo.payload.BroadCastRequest;
import com.xxh.chatdemo.payload.GropRequest;
import com.xxh.chatdemo.payload.JoinRequest;
import com.xxh.chatdemo.utils.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Collection;
import java.util.Set;
import java.util.UUID;

@Component
@Slf4j
public class MessageEventHandler {

    @Autowired
    RedisUtil redisUtil;

    @Autowired
    private SocketIOServer server;

    /**
     * 添加connect事件，当客户端发起连接时调用
     *
     * @param client 客户端对象
     */
    @OnConnect
    public void onConnect(SocketIOClient client) {
        if (client != null) {
            String token = client.getHandshakeData().getSingleUrlParam("token");
            // 模拟用户id 和token一致
            String userId = client.getHandshakeData().getSingleUrlParam("token");
            UUID sessionId = client.getSessionId();
            redisUtil.set(userId, String.valueOf(sessionId));
            log.info("连接成功,【token】= {},【sessionId】= {}", token, sessionId);
        } else {
            log.error("客户端为空");
        }
    }

    /**
     * 添加disconnect事件，客户端断开连接时调用，刷新客户端信息
     *
     * @param client 客户端对象
     */
    @OnDisconnect
    public void onDisconnect(SocketIOClient client) {
        if (client != null) {
            String token = client.getHandshakeData().getSingleUrlParam("token");
            // 模拟用户id 和token一致
            String userId = client.getHandshakeData().getSingleUrlParam("token");
            UUID sessionId = client.getSessionId();
            //删除在线用户
            redisUtil.delete(userId);
            log.info("客户端断开连接,【token】= {},【sessionId】= {}", token, sessionId);
            client.disconnect();
        } else {
            log.error("客户端为空");
        }
    }

    /**
     * @param client  发送消息的客户端
     * @param request 请求
     * @param data    客户端发来的消息
     */
    @OnEvent(value = "SB")
    public void onEvent(SocketIOClient client, AckRequest request, BroadCastRequest data) {
        System.out.println("发来消息：" + data);
        //服务器端向该客户端发送消息,客户端通过监听指定事件可以拿到服务端消息
        server.getClient(client.getSessionId()).sendEvent("SB", "你好 data");
        client.sendEvent("SB", "我是服务器发送的信息");

        //服务器向请求事件的客户端发消息，客户端通过回调函数拿到服务端消息。
        request.sendAckData("请先加群！");
    }

    @OnEvent(value = Event.JOIN)
    public void OnJoinChat(SocketIOClient client, AckRequest request, JoinRequest data){
        System.out.println("发来消息：" + data);
        //将该用户加入群聊
        client.joinRoom(data.getGroupID());
        log.info("用户【"+data.getUserID()+"】"+"加入了群聊【"+data.getGroupID()+"】!!");
        //向群内所有用户广播该条消息
        server.getRoomOperations(data.getGroupID()).sendEvent(Event.JOIN,data);
    }

    @OnEvent(value = Event.GROUP)
    public void OnGroup(SocketIOClient client, AckRequest request, GropRequest data){
        log.info("用户发送了群聊消息："+data.getMessage());
        //判断客户端是否在群聊中
        Collection<SocketIOClient> clients = server.getRoomOperations(data.getGropid()).getClients();
        boolean inRoom=false;
        for (SocketIOClient cl:clients){
            if(client.getSessionId().equals(cl.getSessionId())){
                inRoom=true;
            }
        }
        if(inRoom){
            //向群内所有用户广播该条消息
            server.getRoomOperations(data.getGropid()).sendEvent(Event.GROUP,data);
        }else {
            //向该用户提示请先加群
            data.setGropid("-1");
            data.setMessage("请加群聊后再发言");
            client.sendEvent(Event.GROUP,data);
        }
    }
    /**
     * 广播消息
     *
     * @param message 消息内容
     */
    public void SendBroadCast(BroadCastRequest message) {
        Collection<SocketIOClient> clients = server.getAllClients();
        for(SocketIOClient c:clients){
            c.sendEvent(Event.BRODACAST,message);
        }
    }
}
